Import("env")

env.Tool("DocBook", toolpath = ["#/BuildTools/DocBook/SCons"])

################################################################################
# Code generation helper
################################################################################

import sys, re, os.path

def generateDocBookCode(env, target, source) :
	# Strips empty lines from the beginning & end of a program
	def stripEmptyLines(program) :
		programLines = program.split('\n')
		newProgramLines = []
		inProgram = False
		for line in programLines :
			if not re.match("^\s*$", line) or inProgram :
				inProgram = True
				newProgramLines.append(line)
		return '\n'.join(newProgramLines).rstrip()

	def createCallouts(program, calloutPrefix) :
		newProgramLines = []
		calloutLines = []
		nextID = 0
		for line in program.split("\n") :
			# FIXME: Takes the largest match
			m = re.match(".*\/* \(\*\) (.*) \*/.*", line)
			if m :
				cobID = "cob-" + calloutPrefix + "-" + str(nextID)
				coID = "co-" + calloutPrefix + "-" + str(nextID)
				nextID += 1
				line = re.sub("/\*.*\*/", "]]><co id=\"%(cobID)s\" linkends=\"%(coID)s\"/><![CDATA[" % {"cobID" : cobID, "coID" : coID}, line)
				calloutLines.append("<callout arearefs=\"%(cobID)s\" id=\"%(coID)s\"><para>%(text)s</para></callout>" % {"cobID": cobID, "coID": coID, "text": m.group(1)})
			newProgramLines.append(line)
			callouts = ""
			if len(calloutLines) > 0 :
				callouts = "<calloutlist>" + "\n".join(calloutLines) + "</calloutlist>"
		return ("\n".join(newProgramLines), callouts)

	# Parse program
	filename = source[0].abspath
	filenameBase = os.path.basename(filename).replace(".cpp", "")
	inputfile = open(filename)
	program = ""
	programs = {}
	programName = ""
	inEllipsis = False
	for line in inputfile.readlines() :
		if inEllipsis :
			if "//..." in line :
				inEllipsis = False
		else :
			if line.startswith("/*") or line.startswith(" *") :
				continue
			if "//..." in line :
				inEllipsis = True
				line = line.replace("//...", "]]>&#x2026;<![CDATA[")
			else :
				m = re.match("^/// (.*)", line)
				if m :
					if programName :
						programs[programName] = program
					program = ""
					programName = m.group(1).strip().replace(" ", "")
					continue
			line = re.sub("\t", "  ", line)
			program += line
	programs[programName] = program
	inputfile.close()

	for programName, program in programs.items() :
		program = stripEmptyLines(program)
		(program, callouts) = createCallouts(program, filenameBase + "-" + programName)

		document = "<foo><programlisting><![CDATA[" + program + "]]></programlisting>" + callouts + "</foo>"

		# Generate code
		output = open(target[0].abspath, 'w')
		output.write(document)
		output.close()

################################################################################

if "doc" in ARGUMENTS :
	env.DocBook("Swiften Developers Guide.xml")

sources = []
for i in range(1, 7) :
	sources.append("Examples/EchoBot/EchoBot" + str(i) + ".cpp")
sources.append("Examples/EchoBot/EchoBot0x.cpp")
sources += ["Examples/EchoBot/" + i for i in ["EchoPayloadParserFactory.h", "EchoPayloadSerializer.h", "EchoPayload.h", "EchoComponent.cpp"]]
for source in sources :
	env.Command(source + ".xml", source, Action(generateDocBookCode, cmdstr = "$GENCOMSTR"))

SConscript(dirs = ["Examples"])
